﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using BusinessLogicLayer.Base;
using DALLayer.Providers;
using DataDefinition;
using Objects;

namespace BusinessLogicLayer.Manager
{
    public class UserManager : ManagerBase<UserDataProvider>
    {
        #region [Constructor]
         /// <summary>
        /// Initializes a new instance of the <see cref="UserManager" /> class.
        /// </summary>
        public UserManager() { }
        #endregion

        #region [Manager base class implementations]
        /// <summary>
        /// Pass the data provider to the class
        /// </summary>
        protected override void InitializeDataProvider()
        {
            //Pass the specific data provider to the manager class
            base.DataProvider = new UserDataProvider();
        }

        #endregion


        #region [Public Methods]
        /// <summary>
        /// Update or insert a user.
        /// </summary>
        /// <param name="user">user object</param>
        /// <returns>true or false</returns>
        public bool UpdateUser(User user)
        {
            bool success = false;
            try
            {
                //if there is an id
                if (user.UserID > 0)
                {
                    //Update the user
                    success = base.DataProvider.UpdateUser(user.UserID,user.FirstName, user.LastName, user.EmailAddress, user.UserName, user.Password, user.ProfilePictureURL, user.City, user.Country, user.PhoneNumber, user.UserTypeID, user.IsActive);
                }
                else
                {
                    //Insert an user
                    success = base.DataProvider.InsertUser(user.FirstName, user.LastName, user.EmailAddress, user.UserName, user.Password, user.ProfilePictureURL, user.City, user.Country, user.PhoneNumber, user.UserTypeID, user.IsActive);

                }
            }
            catch (Exception eX)
            {
                // log the error here
            }
            //returns true or false
            return success;

        }
        /// <summary>
        /// Gets user details by article id
        /// </summary>
        /// <param name="articleId">articleId</param>
        /// <returns>user list</returns>
        public List<GetUserByArticleID> GetUserByArticleID(int articleId)
        {
            //The user details
            List<GetUserByArticleID> userDetails = null;
            try
            {
                //Get the data set returned from the data provider
                AutoFixDataSet dataSet = this.DataProvider.GetUserByArticleID(articleId);

                if (dataSet != null && dataSet.GetUserArticleID != null && dataSet.GetUserArticleID.Rows != null)
                {
                    //Set the returned filled list
                    userDetails = FillGetUserArticleIDObjectsByEntities(dataSet.GetUserArticleID);
                }
            }
            catch (Exception eX)
            {
                //log error here
            }
            //The user details list to return
            return userDetails;
        }

        /// <summary>
        /// Gets all the users
        /// </summary>
        /// <returns>user list</returns>
        public List<User> GetUsers()
        {
            //The user details
            List<User> userDetails = null;
            try
            {
                //Get the user details list
                userDetails = this.GetUsers(0, false);
            }
            catch (Exception eX)
            {
                //log error here
            }
            //The user details list to return
            return userDetails;
        }
        /// <summary>
        ///  Gets the users by id
        /// </summary>
        /// <param name="userId">the user id</param>
        /// <returns>user list</returns>
        public List<User> GetUsers(int userId)
        {
            //The user details
            List<User> userDetails = null;
            try
            {
                //Get the user details list
                userDetails = this.GetUsers(userId, true);
            }
            catch (Exception eX)
            {
                //log error here
            }
            //The user details list to return
            return userDetails;

        }
        /// <summary>
        /// Authenticates the user.
        /// </summary>
        /// <param name="email">email</param>
        /// <param name="password">The password.</param>
        /// <returns>user</returns>
        public User AuthenticateUser(string email, string password)
        {
            User appUser = null;

            try
            {
                AutoFixDataSet dataSet = base.DataProvider.AuthenticateUser(email, password);

                if (dataSet != null && dataSet.ApplicationUser != null && dataSet.ApplicationUser.Rows != null)
                {
                    List<User> userDetails = FillUserObjectsByEntities(dataSet.ApplicationUser);

                    if (userDetails != null && userDetails.Count > 0 && userDetails[0] != null)
                    {
                        appUser = userDetails[0];
                    }
                }
            }
            catch (Exception eX)
            {
                //log the error here, dont throw the exception
            }

            return appUser;
        }
        #endregion

        #region [Private Methods]
        /// <summary>
        /// The method that gets the list of users or just one user
        /// </summary>
        /// <param name="userId">user id</param>
        /// <param name="selectById">The check to see if select by id or not</param>
        /// <returns>user list</returns>
        private List<User> GetUsers(int userId, bool selectById)
        {
            //The user details to be returned
            List<User> userDetails = null;
            try
            {
                //Get the data set returned from the data provider
                AutoFixDataSet dataSet = base.DataProvider.GetUserDetails(userId, selectById);

                if (dataSet != null && dataSet.ApplicationUser != null && dataSet.ApplicationUser.Rows != null)
                {
                    //Set the returned filled list
                    userDetails = FillUserObjectsByEntities(dataSet.ApplicationUser);
                }
            }
            catch (Exception eX)
            {
                //log the error here, dont throw the exception
            }
            //Return the user details list
            return userDetails;

        }
        /// <summary>
        /// <summary>
        /// Fill the user object
        /// </summary>
        /// <param name="dataTable">data table</param>
        /// <returns>the user list</returns>
        private List<User> FillUserObjectsByEntities(AutoFixDataSet.ApplicationUserDataTable dataTable)
        {
            //The user list that contains the objects
            //Loop through the data table and create new UserObject 
            //finally select the UserObject and convert to list
            List<User> userDetails = (from uo in
                                                (from u in dataTable.AsEnumerable<AutoFixDataSet.ApplicationUserRow>()
                                                 select new
                                                 {
                                                     UserObject = new User()
                                                     {
                                                         UserID = u.UserID,
                                                         FirstName = u.FirstName,
                                                         LastName = u.LastName,
                                                         EmailAddress = u.EmailAddress,
                                                         UserName = u.UserName,
                                                         Password = u.Password,
                                                         ProfilePictureURL = u.ProfilePictureURL,
                                                         City = u.City,
                                                         Country = u.Country,
                                                         PhoneNumber = u.PhoneNumber,
                                                         UserTypeID = u.UserTypeID,
                                                         IsActive = u.IsActive
                                                     }
                                                 })
                                            select uo.UserObject).ToList();
            //Return the filled user details list
            return userDetails;
        }

        /// <summary>
        /// <summary>
        /// Fill the user object
        /// </summary>
        /// <param name="dataTable">data table</param>
        /// <returns>the user list</returns>
        private List<GetUserByArticleID> FillGetUserArticleIDObjectsByEntities(AutoFixDataSet.GetUserArticleIDDataTable dataTable)
        {
            //The user list that contains the objects
            //Loop through the data table and create new UserObject 
            //finally select the UserObject and convert to list
            List<GetUserByArticleID> userDetails = (from uo in
                                                        (from u in dataTable.AsEnumerable<AutoFixDataSet.GetUserArticleIDRow>()
                                                         select new
                                                         {
                                                             UserObject = new GetUserByArticleID()
                                                             {
                                                                 UserID = u.UserID,
                                                                 UserName = u.UserName,
                                                                 ProfilePictureURL = u.ProfilePictureURL
                                                             }
                                                         })
                                                    select uo.UserObject).ToList();
            //Return the filled user details list
            return userDetails;
        }
        #endregion
    }
}
